package fileoutputobjects;

import java.util.ArrayList;
import java.util.Random;

import user.data.Data;

public class DeliberatePathWalker extends HumanSimulator
{
    private MutableInteger idObject;
    ArrayList<Double> nextXCoord;
    ArrayList<Double> nextZCoord;
    double speed = 0.05;
    double minSpeed = 0.02;
    double maxSpeed = 0.1;
    double finalX;
    double finalZ;
	public DeliberatePathWalker(MutableInteger ID, Random r)
	{
		idObject = ID;
		setRandom(r);
		setNewPosition();
	}
	private void setNewPosition()
	{
		speed = myRandom.nextDouble() * (maxSpeed - minSpeed) + minSpeed;
		randomizeAttributes();
		myID = idObject.intValue();
		idObject.increment();
		nextXCoord = new ArrayList<Double>();
		nextZCoord = new ArrayList<Double>();
		int startPointIndex = myRandom.nextInt(Data.PATH_STARTS.length);
		myXCoord = Data.PATH_STARTS[startPointIndex][0];
		myZCoord = Data.PATH_STARTS[startPointIndex][1];
		int numMidpoints = myRandom.nextInt(Data.PATH_MIDPOINTS.length + 1);
		int arrayLength = Data.PATH_MIDPOINTS.length;
		for (int i = 0; i < numMidpoints; i++)
		{
			int nextPointIndex = myRandom.nextInt(arrayLength);
			nextXCoord.add(Data.PATH_MIDPOINTS[nextPointIndex][0]);
			nextZCoord.add(Data.PATH_MIDPOINTS[nextPointIndex][1]);
		}
		int endPointIndex = myRandom.nextInt(Data.PATH_STARTS.length);
		nextXCoord.add(Data.PATH_STARTS[endPointIndex][0]);
		nextZCoord.add(Data.PATH_STARTS[endPointIndex][1]);
		finalX = nextXCoord.get(nextXCoord.size() - 1);
		finalZ = nextZCoord.get(nextZCoord.size() - 1);
	}
	public void step()
	{
		double lastX = myXCoord;
		double lastZ = myZCoord;
		double hypotenuse = Math.pow(Math.pow(myXCoord - nextXCoord.get(0), 2.0) + 
										Math.pow(myZCoord - nextZCoord.get(0), 2.0), 0.5);
		myXCoord = myXCoord + (nextXCoord.get(0) - myXCoord) * speed / hypotenuse;
		myZCoord = myZCoord + (nextZCoord.get(0) - myZCoord) * speed / hypotenuse;
		boolean hasRecalculated = false;
		if (!isInBounds())
		{
			myXCoord = lastX;
			myZCoord = lastZ;
			recalculate();
			step();
			hasRecalculated = true;
		}
		if (Math.abs(lastX - nextXCoord.get(0)) < Math.abs(myXCoord - nextXCoord.get(0)) && !hasRecalculated)
			recalculate();
	}
	private void recalculate()
	{
		double[] pointRemoved = new double[2];
		pointRemoved[0] = nextXCoord.remove(0);
		pointRemoved[1] = nextZCoord.remove(0);
		if (nextXCoord.size() == 0)
			setNewPosition();
	}
}
